1   /* Generated By:JavaCC: Do not edit this line. StandardSyntaxParser.java */
2   package org.apache.lucene.queryparser.flexible.standard.parser;
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one or more
6    * contributor license agreements.  See the NOTICE file distributed with
7    * this work for additional information regarding copyright ownership.
8    * The ASF licenses this file to You under the Apache License, Version 2.0
9    * (the "License"); you may not use this file except in compliance with
10   * the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  import java.io.StringReader;
22  import java.util.Vector;
23  import java.util.Arrays;
24  
25  import org.apache.lucene.queryparser.flexible.messages.Message;
26  import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
27  import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
28  import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
29  import org.apache.lucene.queryparser.flexible.core.nodes.AndQueryNode;
30  import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode;
31  import org.apache.lucene.queryparser.flexible.core.nodes.BoostQueryNode;
32  import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
33  import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode;
34  import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode;
35  import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode;
36  import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode;
37  import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;
38  import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode;
39  import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
40  import org.apache.lucene.queryparser.flexible.core.nodes.QuotedFieldQueryNode;
41  import org.apache.lucene.queryparser.flexible.core.parser.SyntaxParser;
42  import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
43  
44  /**
45   * Parser for the standard Lucene syntax
46   */
47  public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserConstants {
48  
49  
50     // syntax parser constructor
51     public StandardSyntaxParser() {
52       this(new FastCharStream(new StringReader("")));
53    }
54       /** Parses a query string, returning a {@link org.apache.lucene.queryparser.flexible.core.nodes.QueryNode}.
55       *  @param query  the query string to be parsed.
56       *  @throws ParseException if the parsing fails
57       */
58      public QueryNode parse(CharSequence query, CharSequence field) throws QueryNodeParseException {
59        ReInit(new FastCharStream(new StringReader(query.toString())));
60        try {
61          // TopLevelQuery is a Query followed by the end-of-input (EOF)
62          QueryNode querynode = TopLevelQuery(field);
63          return querynode;
64        }
65        catch (ParseException tme) {
66              tme.setQuery(query);
67              throw tme;
68        }
69        catch (Error tme) {
70            Message message = new MessageImpl(QueryParserMessages.INVALID_SYNTAX_CANNOT_PARSE, query, tme.getMessage());
71            QueryNodeParseException e = new QueryNodeParseException(tme);
72              e.setQuery(query);
73              e.setNonLocalizedMessage(message);
74              throw e;
75        }
76      }
77  
78    final public ModifierQueryNode.Modifier Modifiers() throws ParseException {
79    ModifierQueryNode.Modifier ret = ModifierQueryNode.Modifier.MOD_NONE;
80      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
81      case NOT:
82      case PLUS:
83      case MINUS:
84        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
85        case PLUS:
86          jj_consume_token(PLUS);
87                ret = ModifierQueryNode.Modifier.MOD_REQ;
88          break;
89        case MINUS:
90          jj_consume_token(MINUS);
91                   ret = ModifierQueryNode.Modifier.MOD_NOT;
92          break;
93        case NOT:
94          jj_consume_token(NOT);
95                 ret = ModifierQueryNode.Modifier.MOD_NOT;
96          break;
97        default:
98          jj_la1[0] = jj_gen;
99          jj_consume_token(-1);
100         throw new ParseException();
101       }
102       break;
103     default:
104       jj_la1[1] = jj_gen;
105       ;
106     }
107     {if (true) return ret;}
108     throw new Error("Missing return statement in function");
109   }
110 
111 // This makes sure that there is no garbage after the query string
112   final public QueryNode TopLevelQuery(CharSequence field) throws ParseException {
113   QueryNode q;
114     q = Query(field);
115     jj_consume_token(0);
116      {if (true) return q;}
117     throw new Error("Missing return statement in function");
118   }
119 
120 // These changes were made to introduce operator precedence:
121 // - Clause() now returns a QueryNode. 
122 // - The modifiers are consumed by Clause() and returned as part of the QueryNode Object
123 // - Query does not consume conjunctions (AND, OR) anymore. 
124 // - This is now done by two new non-terminals: ConjClause and DisjClause
125 // The parse tree looks similar to this:
126 //       Query ::= DisjQuery ( DisjQuery )*
127 //   DisjQuery ::= ConjQuery ( OR ConjQuery )* 
128 //   ConjQuery ::= Clause ( AND Clause )*
129 //      Clause ::= [ Modifier ] ... 
130   final public QueryNode Query(CharSequence field) throws ParseException {
131   Vector<QueryNode> clauses = null;
132   QueryNode c, first=null;
133     first = DisjQuery(field);
134     label_1:
135     while (true) {
136       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
137       case NOT:
138       case PLUS:
139       case MINUS:
140       case LPAREN:
141       case QUOTED:
142       case TERM:
143       case REGEXPTERM:
144       case RANGEIN_START:
145       case RANGEEX_START:
146       case NUMBER:
147         ;
148         break;
149       default:
150         jj_la1[2] = jj_gen;
151         break label_1;
152       }
153       c = DisjQuery(field);
154        if (clauses == null) {
155            clauses = new Vector<QueryNode>();
156            clauses.addElement(first);
157         }
158         clauses.addElement(c);
159     }
160         if (clauses != null) {
161         {if (true) return new BooleanQueryNode(clauses);}
162       } else {
163           // Handle the case of a "pure" negation query which
164           // needs to be wrapped as a boolean query, otherwise
165           // the returned result drops the negation.
166           if (first instanceof ModifierQueryNode) {
167             ModifierQueryNode m = (ModifierQueryNode) first;
168             if (m.getModifier() == ModifierQueryNode.Modifier.MOD_NOT) {
169               {if (true) return new BooleanQueryNode(Arrays.<QueryNode> asList(m));}
170             }
171           }
172           {if (true) return first;}
173       }
174     throw new Error("Missing return statement in function");
175   }
176 
177   final public QueryNode DisjQuery(CharSequence field) throws ParseException {
178   QueryNode first, c;
179   Vector<QueryNode> clauses = null;
180     first = ConjQuery(field);
181     label_2:
182     while (true) {
183       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
184       case OR:
185         ;
186         break;
187       default:
188         jj_la1[3] = jj_gen;
189         break label_2;
190       }
191       jj_consume_token(OR);
192       c = ConjQuery(field);
193      if (clauses == null) {
194          clauses = new Vector<QueryNode>();
195          clauses.addElement(first);
196      }
197      clauses.addElement(c);
198     }
199     if (clauses != null) {
200       {if (true) return new OrQueryNode(clauses);}
201     } else {
202         {if (true) return first;}
203     }
204     throw new Error("Missing return statement in function");
205   }
206 
207   final public QueryNode ConjQuery(CharSequence field) throws ParseException {
208   QueryNode first, c;
209   Vector<QueryNode> clauses = null;
210     first = ModClause(field);
211     label_3:
212     while (true) {
213       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
214       case AND:
215         ;
216         break;
217       default:
218         jj_la1[4] = jj_gen;
219         break label_3;
220       }
221       jj_consume_token(AND);
222       c = ModClause(field);
223      if (clauses == null) {
224          clauses = new Vector<QueryNode>();
225          clauses.addElement(first);
226      }
227      clauses.addElement(c);
228     }
229     if (clauses != null) {
230       {if (true) return new AndQueryNode(clauses);}
231     } else {
232         {if (true) return first;}
233     }
234     throw new Error("Missing return statement in function");
235   }
236 
237 // QueryNode Query(CharSequence field) :
238 // {
239 // List clauses = new ArrayList();
240 //   List modifiers = new ArrayList();
241 //   QueryNode q, firstQuery=null;
242 //   ModifierQueryNode.Modifier mods;
243 //   int conj;
244 // }
245 // {
246 //   mods=Modifiers() q=Clause(field)
247 //   {
248 //     if (mods == ModifierQueryNode.Modifier.MOD_NONE) firstQuery=q;
249 //     
250 //     // do not create modifier nodes with MOD_NONE
251 //      if (mods != ModifierQueryNode.Modifier.MOD_NONE) {
252 //          q = new ModifierQueryNode(q, mods);
253 //         }
254 //      clauses.add(q);
255 //   }
256 //   (
257 //     conj=Conjunction() mods=Modifiers() q=Clause(field)
258 //     { 
259 //       // do not create modifier nodes with MOD_NONE
260 //         if (mods != ModifierQueryNode.Modifier.MOD_NONE) {
261 //          q = new ModifierQueryNode(q, mods);
262 //         }
263 //          clauses.add(q);
264 //        //TODO: figure out what to do with AND and ORs
265 //   }
266 //   )*
267 //     {
268 //      if (clauses.size() == 1 && firstQuery != null)
269 //         return firstQuery;
270 //       else {
271 //       return new BooleanQueryNode(clauses);
272 //       }
273 //     }
274 // }
275   final public QueryNode ModClause(CharSequence field) throws ParseException {
276   QueryNode q;
277   ModifierQueryNode.Modifier mods;
278     mods = Modifiers();
279     q = Clause(field);
280         if (mods != ModifierQueryNode.Modifier.MOD_NONE) {
281            q = new ModifierQueryNode(q, mods);
282         }
283         {if (true) return q;}
284     throw new Error("Missing return statement in function");
285   }
286 
287   final public QueryNode Clause(CharSequence field) throws ParseException {
288   QueryNode q;
289   Token fieldToken=null, boost=null, operator=null, term=null;
290   FieldQueryNode qLower, qUpper;
291   boolean lowerInclusive, upperInclusive;
292 
293   boolean group = false;
294     if (jj_2_2(3)) {
295       fieldToken = jj_consume_token(TERM);
296       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
297       case OP_COLON:
298       case OP_EQUAL:
299         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
300         case OP_COLON:
301           jj_consume_token(OP_COLON);
302           break;
303         case OP_EQUAL:
304           jj_consume_token(OP_EQUAL);
305           break;
306         default:
307           jj_la1[5] = jj_gen;
308           jj_consume_token(-1);
309           throw new ParseException();
310         }
311                                  field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);
312         q = Term(field);
313         break;
314       case OP_LESSTHAN:
315       case OP_LESSTHANEQ:
316       case OP_MORETHAN:
317       case OP_MORETHANEQ:
318         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
319         case OP_LESSTHAN:
320           operator = jj_consume_token(OP_LESSTHAN);
321           break;
322         case OP_LESSTHANEQ:
323           operator = jj_consume_token(OP_LESSTHANEQ);
324           break;
325         case OP_MORETHAN:
326           operator = jj_consume_token(OP_MORETHAN);
327           break;
328         case OP_MORETHANEQ:
329           operator = jj_consume_token(OP_MORETHANEQ);
330           break;
331         default:
332           jj_la1[6] = jj_gen;
333           jj_consume_token(-1);
334           throw new ParseException();
335         }
336                                                                                                                field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);
337         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
338         case TERM:
339           term = jj_consume_token(TERM);
340           break;
341         case QUOTED:
342           term = jj_consume_token(QUOTED);
343           break;
344         case NUMBER:
345           term = jj_consume_token(NUMBER);
346           break;
347         default:
348           jj_la1[7] = jj_gen;
349           jj_consume_token(-1);
350           throw new ParseException();
351         }
352         if (term.kind == QUOTED) {
353             term.image = term.image.substring(1, term.image.length()-1);
354         }
355         switch (operator.kind) {
356             case OP_LESSTHAN:
357               lowerInclusive = true;
358               upperInclusive = false;
359 
360                qLower = new FieldQueryNode(field,
361                                          "*", term.beginColumn, term.endColumn);
362             qUpper = new FieldQueryNode(field,
363                                  EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn);
364 
365                 break;
366             case OP_LESSTHANEQ:
367               lowerInclusive = true;
368               upperInclusive = true;
369 
370                 qLower = new FieldQueryNode(field,
371                                          "*", term.beginColumn, term.endColumn);
372                 qUpper = new FieldQueryNode(field,
373                                          EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn);
374                 break;
375             case OP_MORETHAN:
376               lowerInclusive = false;
377               upperInclusive = true;
378 
379                 qLower = new FieldQueryNode(field,
380                                          EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn);
381                 qUpper = new FieldQueryNode(field,
382                                          "*", term.beginColumn, term.endColumn);
383                 break;
384             case OP_MORETHANEQ:
385               lowerInclusive = true;
386               upperInclusive = true;
387 
388                 qLower = new FieldQueryNode(field,
389                                          EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn);
390                 qUpper = new FieldQueryNode(field,
391                                          "*", term.beginColumn, term.endColumn);
392                 break;
393             default:
394                 {if (true) throw new Error("Unhandled case: operator="+operator.toString());}
395         }
396         q = new TermRangeQueryNode(qLower, qUpper, lowerInclusive, upperInclusive);
397         break;
398       default:
399         jj_la1[8] = jj_gen;
400         jj_consume_token(-1);
401         throw new ParseException();
402       }
403     } else {
404       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
405       case LPAREN:
406       case QUOTED:
407       case TERM:
408       case REGEXPTERM:
409       case RANGEIN_START:
410       case RANGEEX_START:
411       case NUMBER:
412         if (jj_2_1(2)) {
413           fieldToken = jj_consume_token(TERM);
414           switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
415           case OP_COLON:
416             jj_consume_token(OP_COLON);
417             break;
418           case OP_EQUAL:
419             jj_consume_token(OP_EQUAL);
420             break;
421           default:
422             jj_la1[9] = jj_gen;
423             jj_consume_token(-1);
424             throw new ParseException();
425           }
426                                  field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);
427         } else {
428           ;
429         }
430         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
431         case QUOTED:
432         case TERM:
433         case REGEXPTERM:
434         case RANGEIN_START:
435         case RANGEEX_START:
436         case NUMBER:
437           q = Term(field);
438           break;
439         case LPAREN:
440           jj_consume_token(LPAREN);
441           q = Query(field);
442           jj_consume_token(RPAREN);
443           switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
444           case CARAT:
445             jj_consume_token(CARAT);
446             boost = jj_consume_token(NUMBER);
447             break;
448           default:
449             jj_la1[10] = jj_gen;
450             ;
451           }
452                                                                  group=true;
453           break;
454         default:
455           jj_la1[11] = jj_gen;
456           jj_consume_token(-1);
457           throw new ParseException();
458         }
459         break;
460       default:
461         jj_la1[12] = jj_gen;
462         jj_consume_token(-1);
463         throw new ParseException();
464       }
465     }
466       if (boost != null) {
467       float f = (float)1.0;
468       try {
469         f = Float.valueOf(boost.image).floatValue();
470         // avoid boosting null queries, such as those caused by stop words
471           if (q != null) {
472             q = new BoostQueryNode(q, f);
473           }
474       } catch (Exception ignored) {
475         /* Should this be handled somehow? (defaults to "no boost", if
476              * boost number is invalid)
477              */
478       }
479       }
480       if (group) { q = new GroupQueryNode(q);}
481       {if (true) return q;}
482     throw new Error("Missing return statement in function");
483   }
484 
485   final public QueryNode Term(CharSequence field) throws ParseException {
486   Token term, boost=null, fuzzySlop=null, goop1, goop2;
487   boolean fuzzy = false;
488   boolean regexp = false;
489   boolean startInc=false;
490   boolean endInc=false;
491   QueryNode q =null;
492   FieldQueryNode qLower, qUpper;
493   float defaultMinSimilarity = org.apache.lucene.search.FuzzyQuery.defaultMinSimilarity;
494     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
495     case TERM:
496     case REGEXPTERM:
497     case NUMBER:
498       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
499       case TERM:
500         term = jj_consume_token(TERM);
501                     q = new FieldQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn);
502         break;
503       case REGEXPTERM:
504         term = jj_consume_token(REGEXPTERM);
505                              regexp=true;
506         break;
507       case NUMBER:
508         term = jj_consume_token(NUMBER);
509         break;
510       default:
511         jj_la1[13] = jj_gen;
512         jj_consume_token(-1);
513         throw new ParseException();
514       }
515       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
516       case FUZZY_SLOP:
517         fuzzySlop = jj_consume_token(FUZZY_SLOP);
518                                 fuzzy=true;
519         break;
520       default:
521         jj_la1[14] = jj_gen;
522         ;
523       }
524       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
525       case CARAT:
526         jj_consume_token(CARAT);
527         boost = jj_consume_token(NUMBER);
528         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
529         case FUZZY_SLOP:
530           fuzzySlop = jj_consume_token(FUZZY_SLOP);
531                                                          fuzzy=true;
532           break;
533         default:
534           jj_la1[15] = jj_gen;
535           ;
536         }
537         break;
538       default:
539         jj_la1[16] = jj_gen;
540         ;
541       }
542        if (fuzzy) {
543            float fms = defaultMinSimilarity;
544            try {
545             fms = Float.valueOf(fuzzySlop.image.substring(1)).floatValue();
546            } catch (Exception ignored) { }
547            if(fms < 0.0f){
548                 {if (true) throw new ParseException(new MessageImpl(QueryParserMessages.INVALID_SYNTAX_FUZZY_LIMITS));}
549           } else if (fms >= 1.0f && fms != (int) fms) {
550             {if (true) throw new ParseException(new MessageImpl(QueryParserMessages.INVALID_SYNTAX_FUZZY_EDITS));}
551           }
552           q = new FuzzyQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(term.image), fms, term.beginColumn, term.endColumn);
553        } else if (regexp) {
554          String re = term.image.substring(1, term.image.length()-1);
555          q = new RegexpQueryNode(field, re, 0, re.length());
556        }
557       break;
558     case RANGEIN_START:
559     case RANGEEX_START:
560       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
561       case RANGEIN_START:
562         jj_consume_token(RANGEIN_START);
563                             startInc=true;
564         break;
565       case RANGEEX_START:
566         jj_consume_token(RANGEEX_START);
567         break;
568       default:
569         jj_la1[17] = jj_gen;
570         jj_consume_token(-1);
571         throw new ParseException();
572       }
573       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
574       case RANGE_GOOP:
575         goop1 = jj_consume_token(RANGE_GOOP);
576         break;
577       case RANGE_QUOTED:
578         goop1 = jj_consume_token(RANGE_QUOTED);
579         break;
580       default:
581         jj_la1[18] = jj_gen;
582         jj_consume_token(-1);
583         throw new ParseException();
584       }
585       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
586       case RANGE_TO:
587         jj_consume_token(RANGE_TO);
588         break;
589       default:
590         jj_la1[19] = jj_gen;
591         ;
592       }
593       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
594       case RANGE_GOOP:
595         goop2 = jj_consume_token(RANGE_GOOP);
596         break;
597       case RANGE_QUOTED:
598         goop2 = jj_consume_token(RANGE_QUOTED);
599         break;
600       default:
601         jj_la1[20] = jj_gen;
602         jj_consume_token(-1);
603         throw new ParseException();
604       }
605       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
606       case RANGEIN_END:
607         jj_consume_token(RANGEIN_END);
608                           endInc=true;
609         break;
610       case RANGEEX_END:
611         jj_consume_token(RANGEEX_END);
612         break;
613       default:
614         jj_la1[21] = jj_gen;
615         jj_consume_token(-1);
616         throw new ParseException();
617       }
618       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
619       case CARAT:
620         jj_consume_token(CARAT);
621         boost = jj_consume_token(NUMBER);
622         break;
623       default:
624         jj_la1[22] = jj_gen;
625         ;
626       }
627           if (goop1.kind == RANGE_QUOTED) {
628             goop1.image = goop1.image.substring(1, goop1.image.length()-1);
629           }
630           if (goop2.kind == RANGE_QUOTED) {
631             goop2.image = goop2.image.substring(1, goop2.image.length()-1);
632           }
633 
634           qLower = new FieldQueryNode(field,
635                                    EscapeQuerySyntaxImpl.discardEscapeChar(goop1.image), goop1.beginColumn, goop1.endColumn);
636       qUpper = new FieldQueryNode(field,
637                                    EscapeQuerySyntaxImpl.discardEscapeChar(goop2.image), goop2.beginColumn, goop2.endColumn);
638           q = new TermRangeQueryNode(qLower, qUpper, startInc ? true : false, endInc ? true : false);
639       break;
640     case QUOTED:
641       term = jj_consume_token(QUOTED);
642                       q = new QuotedFieldQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(term.image.substring(1, term.image.length()-1)), term.beginColumn + 1, term.endColumn - 1);
643       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
644       case FUZZY_SLOP:
645         fuzzySlop = jj_consume_token(FUZZY_SLOP);
646         break;
647       default:
648         jj_la1[23] = jj_gen;
649         ;
650       }
651       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
652       case CARAT:
653         jj_consume_token(CARAT);
654         boost = jj_consume_token(NUMBER);
655         break;
656       default:
657         jj_la1[24] = jj_gen;
658         ;
659       }
660          int phraseSlop = 0;
661 
662          if (fuzzySlop != null) {
663            try {
664              phraseSlop = Float.valueOf(fuzzySlop.image.substring(1)).intValue();
665              q = new SlopQueryNode(q, phraseSlop);
666            }
667            catch (Exception ignored) {
668             /* Should this be handled somehow? (defaults to "no PhraseSlop", if
669            * slop number is invalid)
670            */
671            }
672          }
673       break;
674     default:
675       jj_la1[25] = jj_gen;
676       jj_consume_token(-1);
677       throw new ParseException();
678     }
679     if (boost != null) {
680       float f = (float)1.0;
681       try {
682         f = Float.valueOf(boost.image).floatValue();
683         // avoid boosting null queries, such as those caused by stop words
684           if (q != null) {
685             q = new BoostQueryNode(q, f);
686           }
687       } catch (Exception ignored) {
688         /* Should this be handled somehow? (defaults to "no boost", if
689            * boost number is invalid)
690            */
691       }
692     }
693       {if (true) return q;}
694     throw new Error("Missing return statement in function");
695   }
696 
697   private boolean jj_2_1(int xla) {
698     jj_la = xla; jj_lastpos = jj_scanpos = token;
699     try { return !jj_3_1(); }
700     catch(LookaheadSuccess ls) { return true; }
701     finally { jj_save(0, xla); }
702   }
703 
704   private boolean jj_2_2(int xla) {
705     jj_la = xla; jj_lastpos = jj_scanpos = token;
706     try { return !jj_3_2(); }
707     catch(LookaheadSuccess ls) { return true; }
708     finally { jj_save(1, xla); }
709   }
710 
711   private boolean jj_3R_12() {
712     if (jj_scan_token(RANGEIN_START)) return true;
713     return false;
714   }
715 
716   private boolean jj_3R_11() {
717     if (jj_scan_token(REGEXPTERM)) return true;
718     return false;
719   }
720 
721   private boolean jj_3_1() {
722     if (jj_scan_token(TERM)) return true;
723     Token xsp;
724     xsp = jj_scanpos;
725     if (jj_scan_token(15)) {
726     jj_scanpos = xsp;
727     if (jj_scan_token(16)) return true;
728     }
729     return false;
730   }
731 
732   private boolean jj_3R_8() {
733     Token xsp;
734     xsp = jj_scanpos;
735     if (jj_3R_12()) {
736     jj_scanpos = xsp;
737     if (jj_scan_token(27)) return true;
738     }
739     return false;
740   }
741 
742   private boolean jj_3R_10() {
743     if (jj_scan_token(TERM)) return true;
744     return false;
745   }
746 
747   private boolean jj_3R_7() {
748     Token xsp;
749     xsp = jj_scanpos;
750     if (jj_3R_10()) {
751     jj_scanpos = xsp;
752     if (jj_3R_11()) {
753     jj_scanpos = xsp;
754     if (jj_scan_token(28)) return true;
755     }
756     }
757     return false;
758   }
759 
760   private boolean jj_3R_9() {
761     if (jj_scan_token(QUOTED)) return true;
762     return false;
763   }
764 
765   private boolean jj_3R_5() {
766     Token xsp;
767     xsp = jj_scanpos;
768     if (jj_scan_token(17)) {
769     jj_scanpos = xsp;
770     if (jj_scan_token(18)) {
771     jj_scanpos = xsp;
772     if (jj_scan_token(19)) {
773     jj_scanpos = xsp;
774     if (jj_scan_token(20)) return true;
775     }
776     }
777     }
778     xsp = jj_scanpos;
779     if (jj_scan_token(23)) {
780     jj_scanpos = xsp;
781     if (jj_scan_token(22)) {
782     jj_scanpos = xsp;
783     if (jj_scan_token(28)) return true;
784     }
785     }
786     return false;
787   }
788 
789   private boolean jj_3R_4() {
790     Token xsp;
791     xsp = jj_scanpos;
792     if (jj_scan_token(15)) {
793     jj_scanpos = xsp;
794     if (jj_scan_token(16)) return true;
795     }
796     if (jj_3R_6()) return true;
797     return false;
798   }
799 
800   private boolean jj_3R_6() {
801     Token xsp;
802     xsp = jj_scanpos;
803     if (jj_3R_7()) {
804     jj_scanpos = xsp;
805     if (jj_3R_8()) {
806     jj_scanpos = xsp;
807     if (jj_3R_9()) return true;
808     }
809     }
810     return false;
811   }
812 
813   private boolean jj_3_2() {
814     if (jj_scan_token(TERM)) return true;
815     Token xsp;
816     xsp = jj_scanpos;
817     if (jj_3R_4()) {
818     jj_scanpos = xsp;
819     if (jj_3R_5()) return true;
820     }
821     return false;
822   }
823 
824   /** Generated Token Manager. */
825   public StandardSyntaxParserTokenManager token_source;
826   /** Current token. */
827   public Token token;
828   /** Next token. */
829   public Token jj_nt;
830   private int jj_ntk;
831   private Token jj_scanpos, jj_lastpos;
832   private int jj_la;
833   private int jj_gen;
834   final private int[] jj_la1 = new int[26];
835   static private int[] jj_la1_0;
836   static private int[] jj_la1_1;
837   static {
838       jj_la1_init_0();
839       jj_la1_init_1();
840    }
841    private static void jj_la1_init_0() {
842       jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x0,0x20000000,0x0,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
843    }
844    private static void jj_la1_init_1() {
845       jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,};
846    }
847   final private JJCalls[] jj_2_rtns = new JJCalls[2];
848   private boolean jj_rescan = false;
849   private int jj_gc = 0;
850 
851   /** Constructor with user supplied CharStream. */
852   public StandardSyntaxParser(CharStream stream) {
853     token_source = new StandardSyntaxParserTokenManager(stream);
854     token = new Token();
855     jj_ntk = -1;
856     jj_gen = 0;
857     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
858     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
859   }
860 
861   /** Reinitialise. */
862   public void ReInit(CharStream stream) {
863     token_source.ReInit(stream);
864     token = new Token();
865     jj_ntk = -1;
866     jj_gen = 0;
867     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
868     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
869   }
870 
871   /** Constructor with generated Token Manager. */
872   public StandardSyntaxParser(StandardSyntaxParserTokenManager tm) {
873     token_source = tm;
874     token = new Token();
875     jj_ntk = -1;
876     jj_gen = 0;
877     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
878     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
879   }
880 
881   /** Reinitialise. */
882   public void ReInit(StandardSyntaxParserTokenManager tm) {
883     token_source = tm;
884     token = new Token();
885     jj_ntk = -1;
886     jj_gen = 0;
887     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
888     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
889   }
890 
891   private Token jj_consume_token(int kind) throws ParseException {
892     Token oldToken;
893     if ((oldToken = token).next != null) token = token.next;
894     else token = token.next = token_source.getNextToken();
895     jj_ntk = -1;
896     if (token.kind == kind) {
897       jj_gen++;
898       if (++jj_gc > 100) {
899         jj_gc = 0;
900         for (int i = 0; i < jj_2_rtns.length; i++) {
901           JJCalls c = jj_2_rtns[i];
902           while (c != null) {
903             if (c.gen < jj_gen) c.first = null;
904             c = c.next;
905           }
906         }
907       }
908       return token;
909     }
910     token = oldToken;
911     jj_kind = kind;
912     throw generateParseException();
913   }
914 
915   static private final class LookaheadSuccess extends java.lang.Error { }
916   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
917   private boolean jj_scan_token(int kind) {
918     if (jj_scanpos == jj_lastpos) {
919       jj_la--;
920       if (jj_scanpos.next == null) {
921         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
922       } else {
923         jj_lastpos = jj_scanpos = jj_scanpos.next;
924       }
925     } else {
926       jj_scanpos = jj_scanpos.next;
927     }
928     if (jj_rescan) {
929       int i = 0; Token tok = token;
930       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
931       if (tok != null) jj_add_error_token(kind, i);
932     }
933     if (jj_scanpos.kind != kind) return true;
934     if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
935     return false;
936   }
937 
938 
939 /** Get the next Token. */
940   final public Token getNextToken() {
941     if (token.next != null) token = token.next;
942     else token = token.next = token_source.getNextToken();
943     jj_ntk = -1;
944     jj_gen++;
945     return token;
946   }
947 
948 /** Get the specific Token. */
949   final public Token getToken(int index) {
950     Token t = token;
951     for (int i = 0; i < index; i++) {
952       if (t.next != null) t = t.next;
953       else t = t.next = token_source.getNextToken();
954     }
955     return t;
956   }
957 
958   private int jj_ntk() {
959     if ((jj_nt=token.next) == null)
960       return (jj_ntk = (token.next=token_source.getNextToken()).kind);
961     else
962       return (jj_ntk = jj_nt.kind);
963   }
964 
965   private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
966   private int[] jj_expentry;
967   private int jj_kind = -1;
968   private int[] jj_lasttokens = new int[100];
969   private int jj_endpos;
970 
971   private void jj_add_error_token(int kind, int pos) {
972     if (pos >= 100) return;
973     if (pos == jj_endpos + 1) {
974       jj_lasttokens[jj_endpos++] = kind;
975     } else if (jj_endpos != 0) {
976       jj_expentry = new int[jj_endpos];
977       for (int i = 0; i < jj_endpos; i++) {
978         jj_expentry[i] = jj_lasttokens[i];
979       }
980       jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
981         int[] oldentry = (int[])(it.next());
982         if (oldentry.length == jj_expentry.length) {
983           for (int i = 0; i < jj_expentry.length; i++) {
984             if (oldentry[i] != jj_expentry[i]) {
985               continue jj_entries_loop;
986             }
987           }
988           jj_expentries.add(jj_expentry);
989           break jj_entries_loop;
990         }
991       }
992       if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
993     }
994   }
995 
996   /** Generate ParseException. */
997   public ParseException generateParseException() {
998     jj_expentries.clear();
999     boolean[] la1tokens = new boolean[34];
1000     if (jj_kind >= 0) {
1001       la1tokens[jj_kind] = true;
1002       jj_kind = -1;
1003     }
1004     for (int i = 0; i < 26; i++) {
1005       if (jj_la1[i] == jj_gen) {
1006         for (int j = 0; j < 32; j++) {
1007           if ((jj_la1_0[i] & (1<<j)) != 0) {
1008             la1tokens[j] = true;
1009           }
1010           if ((jj_la1_1[i] & (1<<j)) != 0) {
1011             la1tokens[32+j] = true;
1012           }
1013         }
1014       }
1015     }
1016     for (int i = 0; i < 34; i++) {
1017       if (la1tokens[i]) {
1018         jj_expentry = new int[1];
1019         jj_expentry[0] = i;
1020         jj_expentries.add(jj_expentry);
1021       }
1022     }
1023     jj_endpos = 0;
1024     jj_rescan_token();
1025     jj_add_error_token(0, 0);
1026     int[][] exptokseq = new int[jj_expentries.size()][];
1027     for (int i = 0; i < jj_expentries.size(); i++) {
1028       exptokseq[i] = jj_expentries.get(i);
1029     }
1030     return new ParseException(token, exptokseq, tokenImage);
1031   }
1032 
1033   /** Enable tracing. */
1034   final public void enable_tracing() {
1035   }
1036 
1037   /** Disable tracing. */
1038   final public void disable_tracing() {
1039   }
1040 
1041   private void jj_rescan_token() {
1042     jj_rescan = true;
1043     for (int i = 0; i < 2; i++) {
1044     try {
1045       JJCalls p = jj_2_rtns[i];
1046       do {
1047         if (p.gen > jj_gen) {
1048           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
1049           switch (i) {
1050             case 0: jj_3_1(); break;
1051             case 1: jj_3_2(); break;
1052           }
1053         }
1054         p = p.next;
1055       } while (p != null);
1056       } catch(LookaheadSuccess ls) { }
1057     }
1058     jj_rescan = false;
1059   }
1060 
1061   private void jj_save(int index, int xla) {
1062     JJCalls p = jj_2_rtns[index];
1063     while (p.gen > jj_gen) {
1064       if (p.next == null) { p = p.next = new JJCalls(); break; }
1065       p = p.next;
1066     }
1067     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
1068   }
1069 
1070   static final class JJCalls {
1071     int gen;
1072     Token first;
1073     int arg;
1074     JJCalls next;
1075   }
1076 
1077 }